#ifndef BTHREAD_H
#define BTHREAD_H

#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>
#include <algorithm>
using namespace std::chrono_literals; // 线程安全的阻塞队列（生产者-消费者队列）
template<typename T>

class BThread {
    private: std::queue<T> queue_;
        mutable std::mutex mtx_; // mutable 允许在 const 方法中加锁
        std::condition_variable cv_;
        std::atomic<bool> shutdown_{false};
    public:
        BThread() = default;
        ~BThread() = default;
        BThread(const BThread&) = delete;
        BThread& operator=(const BThread&) = delete;
        // 添加元素
        void push(T value) {
            {
                std::scoped_lock lock(mtx_);
                if (shutdown_) {
                    throw std::runtime_error("Cannot push to a shut down queue.");
                }
                queue_.push(std::move(value));
            }
            cv_.notify_one(); // 通知一个消费者
        }
        // 尝试弹出元素，成功返回 true
        bool try_pop(T& value) {
            std::scoped_lock lock(mtx_);
            if (queue_.empty() || shutdown_) {
                return false;
            }
            value = std::move(queue_.front());
            queue_.pop();
            return true;
        }

        // 阻塞弹出
        bool wait_and_pop(T& value, std::chrono::milliseconds timeout = 100ms) {
            std::unique_lock<std::mutex> lock(mtx_);
            if (cv_.wait_for(lock, timeout, [this] { return !queue_.empty() || shutdown_; })) {
                if (!queue_.empty()) {
                    value = std::move(queue_.front());
                    queue_.pop();
                    return true;
                }
            }
            return false;
        }
        // 关闭队列，通知所有等待线程退出
        void close() {
            {
                std::scoped_lock lock(mtx_);
                shutdown_ = true;
            }
            cv_.notify_all();
        }
        bool is_closed() const {
            return shutdown_;
        }
        size_t size() const {
            std::scoped_lock lock(mtx_);
            return queue_.size();
        }
};

#endif // BTHREAD_H
